<template>
  <fs-page>
    <template #header>
      <div class="title">
        菜单管理
        <fs-icon icon="ant-design:menu-outlined" :spin="true" />
      </div>
    </template>
    <n-grid class="mt-10" cols="1 s:1 m:1 l:10 xl:10 2xl:10" responsive="screen" :x-gap="12">
      <n-gi span="2">
        <n-card :segmented="{ content: true }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <n-button type="info" ghost icon-placement="right" @click="openCreateDrawer">
                添加菜单
                <template #icon>
                  <div class="flex items-center">
                    <n-icon size="14">
                      <FileAddTwotone />
                    </n-icon>
                  </div>
                </template>
              </n-button>
              <n-button type="info" ghost icon-placement="left" @click="packHandle">
                全部{{ expandedKeys.length ? '收起' : '展开' }}
                <template #icon>
                  <div class="flex items-center">
                    <n-icon size="14">
                      <AlignLeftOutlined />
                    </n-icon>
                  </div>
                </template>
              </n-button>
            </n-space>
          </template>
          <div class="w-full menu">
            <n-input type="input" v-model:value="pattern" placeholder="输入菜单名称搜索">
              <template #suffix>
                <n-icon size="18" class="cursor-pointer">
                  <SearchOutlined />
                </n-icon>
              </template>
            </n-input>
            <div class="py-3 menu-list">
              <template v-if="loading">
                <div class="flex items-center justify-center py-4">
                  <n-spin size="medium" />
                </div>
              </template>
              <template v-else>
                <n-tree
                  block-line
                  cascade
                  checkable
                  default-expand-all
                  :show-irrelevant-nodes="false"
                  :virtual-scroll="true"
                  :pattern="pattern"
                  :key-field="`id`"
                  :data="treeData"
                  :expandedKeys="expandedKeys"
                  style="max-height: 650px; overflow: hidden"
                  @update:selected-keys="selectedTree"
                  @update:expanded-keys="onExpandedKeys"
                />
              </template>
            </div>
          </div>
        </n-card>
      </n-gi>
      <n-gi span="4">
        <n-card :segmented="{ content: true }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <n-icon size="18">
                <FormOutlined />
              </n-icon>
              <span>编辑菜单{{ treeItemTitle ? `：${treeItemTitle}` : '' }}</span>
            </n-space>
          </template>
          <n-alert type="info" closable> 从菜单列表选择一项后，进行编辑</n-alert>
          <n-form
            :model="formParams"
            :rules="rules"
            ref="formRef"
            label-placement="left"
            :label-width="100"
            v-if="isEditMenu"
            class="py-4"
          >
            <n-form-item label="上级菜单ID" path="parentId">
              <n-input-number :show-button="false" disabled v-model:value="formParams.parentId" />
            </n-form-item>
            <n-form-item label="名称" path="label">
              <n-input placeholder="请输入名称" v-model:value="formParams.label" />
            </n-form-item>
            <n-form-item label="图标" path="icon">
              <n-input placeholder="请输入图标" v-model:value="formParams.icon" />
            </n-form-item>
            <n-form-item label="类型" path="type">
              <n-radio-group v-model:value="formParams.type" name="type">
                <n-space>
                  <n-radio :value="1">菜单</n-radio>
                </n-space>
              </n-radio-group>
            </n-form-item>
            <n-form-item label="路径" path="path">
              <n-input placeholder="请输入路径" v-model:value="formParams.path" />
            </n-form-item>
            <n-form-item label="组件" path="component">
              <n-input placeholder="请输入组件" v-model:value="formParams.component" />
            </n-form-item>
            <n-form-item label="状态" path="status">
              <n-radio-group v-model:value="formParams.status" name="status">
                <n-space>
                  <n-radio :value="1">启用</n-radio>
                  <n-radio :value="0">禁用</n-radio>
                </n-space>
              </n-radio-group>
            </n-form-item>
            <n-form-item label="全局" path="global">
              <n-radio-group v-model:value="formParams.global" name="global">
                <n-space>
                  <n-radio :value="1">是</n-radio>
                  <n-radio :value="0">否</n-radio>
                </n-space>
              </n-radio-group>
            </n-form-item>
            <n-form-item label="排序" path="sequence">
              <n-input-number
                :show-button="false"
                placeholder="请输入排序"
                v-model:value="formParams.sequence"
              />
            </n-form-item>
            <n-form-item label="描述" path="description">
              <n-input
                type="textarea"
                placeholder="请输入描述"
                v-model:value="formParams.description"
              />
            </n-form-item>
            <n-form-item path="auth" style="margin-left: 100px">
              <n-space>
                <n-button type="primary" :loading="subLoading" @click="formSubmit"
                  >保存修改</n-button
                >
                <n-button type="warning" @click="handleReset">重置</n-button>
                <n-button type="error" @click="handleDel">删除</n-button>
              </n-space>
            </n-form-item>
          </n-form>
        </n-card>
      </n-gi>
      <n-gi span="4">
        <n-card :segmented="{ content: true }" :bordered="false" size="small" style="height: 800px">
          <fs-crud ref="crudRef" v-bind="crudBinding" />
        </n-card>
      </n-gi>
    </n-grid>
    <CreateDrawer
      ref="createDrawerRef"
      @loadMenuTree="loadMenuTree"
      :title="drawerTitle"
      :parentId="treeItemParentId"
    />
  </fs-page>
</template>
<!--<script lang="ts" setup>-->
<script>
  import { defineComponent, ref, unref, reactive, onMounted } from 'vue';
  import { useDialog, useMessage } from 'naive-ui';
  import { FileAddTwotone, AlignLeftOutlined, SearchOutlined, FormOutlined } from '@vicons/antd';
  import { getMenuList } from '@/api/system/menu';
  import { getTreeItemById } from '@/utils';
  import CreateDrawer from './CreateDrawer.vue';
  import { SaveOrUpdate, DelObj } from './api';
  import createCrudOptions from './crud';
  import { useExpose, useCrud } from '@fast-crud/fast-crud';

  export default defineComponent({
    name: 'AccountManagement',
    components: {
      FileAddTwotone,
      AlignLeftOutlined,
      SearchOutlined,
      FormOutlined,
      CreateDrawer,
    },
    setup() {
      const rules = {
        parentId: {
          type: 'number',
          required: true,
          message: '请输入上级菜单ID',
          trigger: ['change', 'blur'],
        },
        label: {
          required: true,
          message: '请输入名称',
          trigger: 'blur',
        },
        type: {
          type: 'number',
          required: true,
          message: '请选择类型',
          trigger: ['change', 'blur'],
        },
        path: {
          required: true,
          message: '请输入路径',
          trigger: 'blur',
        },
      };

      const formRef = ref(null);
      const createDrawerRef = ref();
      const message = useMessage();
      const dialog = useDialog();

      let treeItemKey = ref([]);

      let expandedKeys = ref([]);

      const treeData = ref([]);

      const loading = ref(true);
      const subLoading = ref(false);
      const isEditMenu = ref(false);
      const treeItemTitle = ref('');
      const treeItemParentId = ref(0);
      const pattern = ref('');
      const drawerTitle = ref('');

      const formParams = reactive({
        id: null,
        parentId: null,
        label: null,
        icon: null,
        type: 1,
        path: null,
        component: null,
        status: 1,
        global: 0,
        sequence: 0,
        description: null,
      });

      const nodeRef = ref();

      const crudRef = ref();
      const crudBinding = ref();
      const { expose } = useExpose({ crudRef, crudBinding });
      const { crudOptions } = createCrudOptions({ expose, nodeRef });
      useCrud({ expose, crudOptions, permission: 'station:management' });

      function openCreateDrawer() {
        if (treeItemKey.value.length > 0) {
          drawerTitle.value = `父级菜单：${treeItemTitle.value}`;
          const { openDrawer } = createDrawerRef.value;
          openDrawer();
        } else {
          drawerTitle.value = `父级菜单：顶级根菜单`;
          const { openDrawer } = createDrawerRef.value;
          openDrawer();
        }
      }

      function selectedTree(keys) {
        if (keys.length) {
          const treeItem = getTreeItemById(unref(treeData), keys[0]);
          treeItemKey.value = keys;
          treeItemTitle.value = treeItem.label;
          treeItemParentId.value = treeItem.id;
          Object.assign(formParams, treeItem);
          formParams.status = formParams.status ? 1 : 0;
          formParams.global = formParams.global ? 1 : 0;
          isEditMenu.value = true;
          nodeRef.value = keys[0];
          crudBinding.value.actionbar.buttons.add.show = true;
          expose.doRefresh();
        } else {
          isEditMenu.value = false;
          treeItemKey.value = [];
          treeItemTitle.value = '';
          treeItemParentId.value = 0;
          nodeRef.value = '-99999';
          crudBinding.value.actionbar.buttons.add.show = false;
          expose.doRefresh();
        }
      }

      function handleDel() {
        dialog.info({
          title: '提示',
          content: `您确定想删除此菜单信息吗?`,
          positiveText: '确定',
          negativeText: '取消',
          onPositiveClick: () => {
            DelObj(formParams.id).then(() => {
              message.success('操作成功', { duration: 3 });
              loadMenuTree();
            });
          },
        });
      }

      function handleReset() {
        const treeItem = getTreeItemById(unref(treeData), treeItemKey.value[0]);
        Object.assign(formParams, treeItem);
        formParams.status = formParams.status ? 1 : 0;
        formParams.global = formParams.global ? 1 : 0;
      }

      function formSubmit() {
        formRef.value.validate((errors) => {
          if (!errors) {
            SaveOrUpdate(formParams).then(() => {
              message.success('操作成功', { duration: 3 });
            });
          } else {
            message.error('请填写完整菜单信息');
          }
        });
      }

      function packHandle() {
        if (expandedKeys.value.length) {
          expandedKeys.value = [];
        } else {
          expandedKeys.value = unref(treeData).map((item) => item.id);
        }
      }

      async function loadMenuTree() {
        const treeMenuList = await getMenuList();
        if (treeMenuList) {
          const keys = treeMenuList.map((item) => item.id);
          Object.assign(formParams, keys);
          treeData.value = treeMenuList;
          expandedKeys.value = unref(treeData).map((item) => item.id);
          selectedTree([]);
        }
        loading.value = false;
      }

      onMounted(async () => {
        await loadMenuTree();
        // expose.doRefresh();
      });

      function onExpandedKeys(keys) {
        expandedKeys.value = keys;
      }

      return {
        rules,
        formRef,
        createDrawerRef,
        treeItemKey,
        expandedKeys,
        treeData,
        loading,
        subLoading,
        isEditMenu,
        treeItemTitle,
        treeItemParentId,
        pattern,
        drawerTitle,
        formParams,

        nodeRef,
        crudRef,
        crudBinding,

        openCreateDrawer,
        selectedTree,
        handleDel,
        handleReset,
        formSubmit,
        packHandle,
        loadMenuTree,
        onExpandedKeys,
      };
    },
  });
</script>
